﻿<template>
    <div
        class="text-box"
        :style="{
            left: `${schema.x}px`,
            top: `${schema.y}px`,
            width: `${textBoxWidth}px`,
            height: `${textBoxHeight}px`,
        }"
        :class="schema.isActive ? 'active' : ''"
        @click="startDrop"
        ref="textBoxRef"
    >
        <!-- 扩展宽度 -->
        <div class="resize-box" v-if="schema.isActive" @mousedown="startResize"></div>

        <!-- 文本盒子 -->
        <div class="text-content" @mousedown="startDragging" @dblclick="handleDoubleClick">
            <div class="show" :style="{ lineHeight: `${textBoxHeight}px` }" v-if="!isEdit">{{ dtoValue }}</div>
            <input
                v-else
                ref="inputRef"
                class="input"
                :id="schema.id"
                type="text"
                v-model="dtoValue"
                @blur="onBlur"
                @input="onInput"
                autocomplete="off"
            />
        </div>
    </div>
</template>

<script setup>
import { ref, onMounted, watch, nextTick, defineProps, defineEmits, toRefs, reactive } from 'vue';
import { limitInputWidth } from '@/utils/utils';
const props = defineProps(['schema']);
const { schema } = toRefs(props);
const $emits = defineEmits(['updateText', 'moveComponent', 'changeStyle', 'startDrop']);

let startX = 0;
let startY = 0;
let initialX = 0;
let initialY = 0;

const dtoValue = ref('');

const isEdit = ref(false);

//移动
const startDrop = e => {
    e.stopPropagation();
    $emits('startDrop', schema.value.id);
};

const startDragging = e => {
    if (!schema.value.isActive) return;
    // 鼠标按下的位置
    startX = e.clientX;
    startY = e.clientY;

    // 组件原始位置
    initialX = schema.value.x;
    initialY = schema.value.y;

    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleMouseUp);
};

const textBoxRef = ref(null);
const handleMouseMove = e => {
    // 移动的距离
    const dx = e.clientX - startX;
    const dy = e.clientY - startY;

    // 计算新位置并发出事件(相对于pdfView的位置)
    const newX = initialX + dx;
    const newY = initialY + dy;

    $emits('moveComponent', {
        x: newX,
        y: newY,
        id: schema.value.id,
        width: parseInt(textBoxRef.value.style.width),
        height: parseInt(textBoxRef.value.style.height),
    });
};

const handleMouseUp = () => {
    document.removeEventListener('mousemove', handleMouseMove);
    document.removeEventListener('mouseup', handleMouseUp);
};

// 双击编辑
const inputRef = ref(null);
let cleanup = null;
const handleDoubleClick = async () => {
    isEdit.value = true;
    await nextTick();
    inputRef.value.focus();
    // cleanup = limitInputWidth(inputRef.value, parseInt(textBoxRef.value.style.width));
};

const onBlur = () => {
    isEdit.value = false;
};

// 更新文本
const onInput = e => {
    $emits('updateText', { val: e.target.value, id: schema.value.id });
};

// 调整宽度
const isResizing = ref(false);
const textBoxWidth = ref(0);
const textBoxHeight = ref(0);
const textStartX = ref(0);
const tempWidth = ref(0);

const startResize = e => {
    if (e.target.classList.contains('resize-box')) {
        e.preventDefault();
        isResizing.value = true;
        // 鼠标开始的位置
        textStartX.value = e.clientX;
        tempWidth.value = textBoxWidth.value;
        // 添加全局事件监听器
        document.addEventListener('mousemove', handleResize);
        document.addEventListener('mouseup', stopResize);
    }
};

// 处理调整宽度
const handleResize = e => {
    if (!isResizing.value) return;

    // 鼠标拖动的距离
    const deltaX = e.clientX - textStartX.value;

    const newWidth = Math.max(100, tempWidth.value + deltaX); // 最小宽度50px

    textBoxWidth.value = newWidth;
    // 保存
    $emits('changeStyle', { width: textBoxWidth.value, height: textBoxHeight.value, id: schema.value.id });
};

// 停止调整宽度
const stopResize = () => {
    isResizing.value = false;
    document.removeEventListener('mousemove', handleResize);
    document.removeEventListener('mouseup', stopResize);
};

const initData = () => {
    dtoValue.value = schema.value.val;
    textBoxWidth.value = schema.value.width;
    textBoxHeight.value = schema.value.height;
};

watch(
    [schema],
    () => {
        initData();
    },
    { immediate: true, deep: true }
);

onMounted(() => {});
</script>

<style scoped lang="scss">
.text-box {
    position: absolute;
    left: 0;
    top: 0;
    padding: 0 2px;
    user-select: none;
    display: flex;
    align-items: center;
    border-width: 2px;
    border-style: solid;
    border-color: transparent;
    &:hover {
        border-color: #3673c2;
    }
    .resize-box {
        position: absolute;
        top: -2px;
        right: -5px;
        height: calc(100% + 4px);
        width: 5px;
        background-color: #3673c2;
        cursor: ew-resize;
    }
    .text-content {
        height: 100%;
        width: 100%;
        cursor: move;
        .show {
            height: 100%;
            width: 100%;
        }
        .input {
            height: 100%;
            width: 100%;
            background-color: #cddcf0;
        }
    }
}
.active {
    border-color: #3673c2;
    background-color: #cddcf0;
}
</style>
